package com.example.musicplayer.controller;

import com.example.musicplayer.mapper.LoveMusicMapper;
import com.example.musicplayer.mapper.MusicMapper;
import com.example.musicplayer.model.Music;
import com.example.musicplayer.model.User;
import com.example.musicplayer.tools.Constant;
import com.example.musicplayer.tools.ResponseBodyMessage;
import org.apache.ibatis.binding.BindingException;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.multipart.MultipartFile;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
import java.io.File;
import java.io.IOException;
import java.nio.file.Files;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.List;

@RestController
@RequestMapping("/music")
public class MusicController {

    @Value("${music.local.path}")
    private String SAVE_PATH;

    @Autowired
    private MusicMapper musicMapper;

    @Autowired
    private LoveMusicMapper loveMusicMapper;

    /**
     * 上传音乐
     * @param singer 歌手名
     * @param file 上传的音乐文件
     * @param request 获取用户是否登录
     * @return 返回报文
     */
    @RequestMapping("/upload")
    public ResponseBodyMessage<Boolean> insertMusic(String singer,
                                                    @RequestParam("filename") MultipartFile file,
                                                    HttpServletRequest request, HttpServletResponse response){
        //检查是否登录
        HttpSession session = request.getSession(false);
        if (session == null || session.getAttribute(Constant.USERINFO_SESSION_KEY) == null){
            return new ResponseBodyMessage<>(0, "请登录后上传", false);
        }

        //检查数据库中是否有歌名和歌手相同的数据
        String fileName = file.getOriginalFilename();// 获取文件名
        int index = fileName.lastIndexOf(".");// 存不用加后缀
        String title = fileName.substring(0, index);
        Music music = musicMapper.selectSame(title, singer);
        if (music != null){
            return new ResponseBodyMessage<>(0, "请勿重复上传", false);
        }

        //上传服务器
        String path = SAVE_PATH + "/" + fileName;// 指定文件保存路径
        File destFile = new File(path);
        System.out.println("文件路径: " + destFile.getPath());

        if (!destFile.exists()){
            destFile.mkdirs();// 别少加了 s
        }

        try {
            file.transferTo(destFile);// 保存文件到指定路径
        } catch (IOException e) {
            e.printStackTrace();
            return new ResponseBodyMessage<>(0, "上传失败", false);
        }

        //数据库上传
        User user = (User)session.getAttribute(Constant.USERINFO_SESSION_KEY);
        int userid = user.getId();

        //播放音乐, 获取Http请求
        String url = "/music/get?path=" + title;

        //获取时间
        SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd");
        String time = simpleDateFormat.format(new Date());

        //上传数据
        try {
            int ret = 0;
            ret = musicMapper.insert(title, singer, time, url, userid);
            if (ret == 1){
                //可以跳转到音乐列表界面
                response.sendRedirect("/list.html");
                return new ResponseBodyMessage<>(1, "服务器上传成功", true);
            }else {
                return new ResponseBodyMessage<>(0, "服务器上传失败", false);
            }
        }catch (BindingException | IOException e){
            destFile.delete();
            e.printStackTrace();
            return new ResponseBodyMessage<>(0, "服务器上传失败", false);
        }
    }

    /**
     * 音乐播放的方式为GET, 格式为 get?path=xxx.mp3 (取文件需要加后缀)
     * 此方法拓展: 判断是否是正规MP3格式验证
     * @param path 文件路径
     * @return 返回播放音乐文件的报文
     */
    @RequestMapping("/get")
    public ResponseEntity<byte[]> play(String path){
        File file = new File(SAVE_PATH + "/" + path);
        byte[] plays = null;
        try {
            // 找到路径下的文件进行读取
            plays = Files.readAllBytes(file.toPath());
            // 若未获取文件, 返回一个错误请求
            if (plays == null){
                return ResponseEntity.badRequest().build();
            }
            return ResponseEntity.ok(plays);// 正常播放
        } catch (IOException e) {
            e.printStackTrace();
        }
        return ResponseEntity.badRequest().build();
    }

    /**
     * 删除单个音乐
     * @param id 要删除的音乐ID
     * @return 返回报文, 是否删除成功
     */
    @RequestMapping("/delete")
    public ResponseBodyMessage<Boolean> deleteMusicById(@RequestParam String id){
        // 查询删除音乐是否存在
        int deleteId = Integer.parseInt(id); // 前端拿到的都是String类型的
        Music deleteMusic = musicMapper.findById(deleteId);
        if (deleteMusic == null){
            //System.out.println("无此id的音乐");
            return new ResponseBodyMessage<>(0, "删除失败, 没有您要删除的音乐", false);
        }

        // 删除音乐, 并且lovemusic内的音乐也需要删除
        int flag = musicMapper.deleteMusicById(deleteId);
        if (flag == 0){
            return new ResponseBodyMessage<>(0, "数据库音乐删除失败", false);
        }

        //别忘了删除本地文件
        String title = deleteMusic.getTitle();
        File file = new File(SAVE_PATH + "/" + title + ".mp3");
        //System.out.println("当前路径:" + file.getPath());
        if (file.delete()){
            // 同步删除收藏音乐表内的数据
            loveMusicMapper.deleteLoveMusicById(deleteId);
            return new ResponseBodyMessage<>(1, "删除成功", true);
        }
        return new ResponseBodyMessage<>(0, "本地音乐删除失败", false);
    }

    /**
     * 批量进行删除
     * @param id 要删除的音乐ID
     * @return 返回报文, 是否删除成功
     */
    @RequestMapping("/deletes")
    public ResponseBodyMessage<Boolean> deleteMusics(@RequestParam("id[]") List<Integer> id){
        System.out.println("id[]" + id);
        int sum = 0;
        for (int i = 0; i < id.size(); i++) {
            Music deleteMusic = musicMapper.findById(id.get(i));
            if (deleteMusic == null){
                //System.out.println("无此id的音乐");
                return new ResponseBodyMessage<>(0, "删除失败, 没有您要删除的音乐", false);
            }
            int ret = musicMapper.deleteMusicById(id.get(i));
            if (ret == 0){
                return new ResponseBodyMessage<>(0, "数据库音乐删除失败", false);
            }
            String title = deleteMusic.getTitle();
            File file = new File(SAVE_PATH + "/" + title + ".mp3");
            if (file.delete()){
                //这里不能return, 因为要删很多
                loveMusicMapper.deleteLoveMusicById(id.get(i));
                sum += ret;
            }else {
                return new ResponseBodyMessage<>(0, "本地音乐删除失败", false);
            }
        }
        if (sum == id.size()){
            return new ResponseBodyMessage<>(1, "所选全部音乐删除成功", true);
        }
        return new ResponseBodyMessage<>(0, "本地音乐删除失败", false);
    }

    /**
     * 查找音乐
     * @param musicName 用户如果不传参数, 会返回所有音乐
     *                  required = false 代表着参数可以传空
     * @return 返回一个音乐集合
     */
    @RequestMapping("/findmusic")
    public ResponseBodyMessage<List<Music>> findMusic(@RequestParam(required = false) String musicName){
        List<Music> musicList = null;
        if (musicName != null){
            musicList = musicMapper.findMusicByName(musicName);
        }else {
            musicList = musicMapper.findMusic();
        }
        return new ResponseBodyMessage<>(0, "查询到了所有音乐", musicList);
    }
}
